package com.qf.realm;

import com.alibaba.druid.util.StringUtils;
import com.qf.entity.User;
import com.qf.serivce.UserService;
import com.qf.serivce.impl.RoleServiceImpl;
import com.qf.serivce.impl.UserServiceImpl;
import com.qf.service.PermissionService;
import com.qf.service.RoleService;
import com.qf.service.impl.PermissionServiceImpl;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

import java.util.Set;

/**
 * 自定义Realm
 * @author zjw
 * @description
 * @date 2021/10/13 16:04
 */
public class CustomRealm extends AuthorizingRealm {

    private UserService userService = new UserServiceImpl();
    private RoleService roleService = new RoleServiceImpl();
    private PermissionService permissionService = new PermissionServiceImpl();

    {
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
        matcher.setHashAlgorithmName("MD5");
        matcher.setHashIterations(123);
        this.setCredentialsMatcher(matcher);
    }

    /**
     * 认证
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //1. 获取到token中存储的用户名
        String username = (String) token.getPrincipal();
        if(StringUtils.isEmpty(username)){
            throw new AccountException("用户名不允许为null！");
        }

        //2. 根据用户名去数据库查询用户信息
        User user = userService.findByUsername(username);

        //3. 如果查询到的用户信息为null - 用户名错误
        if(user == null){
            throw new UnknownAccountException("用户名输入错误！");
        }

        //4. 将用户信息和密码设置到返回结果中
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassword(),"老子的Realm");
        // 告诉Shiro盐
        info.setCredentialsSalt(ByteSource.Util.bytes(user.getSalt()));

        //5. 返回
        return info;
    }


        /**
         * 授权操作
         * @param principals
         * @return
         */
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
            //1. 获取用户信息
            User user = (User) principals.getPrimaryPrincipal();

            //2. 根据用户信息查询角色信息
            Set<String> roles = roleService.findRolesByUser(user);

            //3. 根据角色信息查询权限信息
            Set<String> permissions = permissionService.findPermissionsByRoles(roles);

            //4. 将角色信息和权限信息封装到AuthorizationInfo中
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            info.addRoles(roles);
            info.addStringPermissions(permissions);

            //5. 返回
            return info;
        }
    /*
        user: 1 - admin

        role: 1 - 超级管理员
              2 - 运营人员
              3 - 测试人员

        permissions：    1 - user:delete
                         2 - item:insert
                         3 - delete:code


     */


}
